#coding=utf-8
from xml.etree import ElementTree as ET
from common import md5

class XMLFileGeneratorException(Exception):
    def __init__(self,args):
        super(XMLFileGeneratorException, self).__init__(args)

def _error(self, msg):
    sys.stderr.write('%s\n'%msg)
    raise XMLFileGeneratorException(msg)

class XMLFileGenerator(object):
    def __init__(self, file):
        self.file = file
        self.et = ET.ElementTree(element=None, file=file)
        self.root_e = self.et.getroot()
    #根据attri {} 来查找对应的element
    def find_element(self, target_attri):

        element = None
        for e in self.et.getiterator():
            isMatch = True
            for key, value in target_attri.items():
                e_value = e.attrib.get(key, None)
                if e_value == None or e_value != value:
                    isMatch = False
            if isMatch:
                element = e
                break
        return element

    def find_parent_element(self, root_e, target_e):

        parent_element = None

        for child in root_e.getchildren():

            ch_law_id = child.attrib.get('law_id', None)
            target_e_law_id = target_e.attrib.get('law_id', None)
            if ch_law_id is not None and target_e_law_id is not None:
                if ch_law_id == target_e_law_id:
                    parent_element = root_e
                else:
                    parent_element = self.find_parent_element(child, target_e)
            else:
                parent_element = self.find_parent_element(child, target_e)

            if parent_element is not None:
                break

        return parent_element

    def get_element_index(self,element,parent_element):
        for index, child in enumerate(parent_element.getchildren()):
            if child == element:
                return index

        return -1

    def remove_all_child(self, element):

        #遍历删除 要对数组进行copy
        children = element.getchildren()[:]
        for child in children:
            element.remove(child)

    #target_attri:增加条款所在的位置  content: 增加的条款
    def add_element(self, target_attri, new_attri, content):
        #print "INFO:####正在增加条款 %s" % str(target_attri)

        pre_added_element = self.find_element(target_attri)
        if pre_added_element is None:
            _error("ERROR:未找到增加条款所在位置的条款: %s" % str(target_attri))
            return False

        parent_e = self.find_parent_element(self.root_e, pre_added_element)
        if parent_e is None:
            _error("ERROR:未找到增加条款的父条款: %s" % str(target_attri))
            return False

        index = self.get_element_index(pre_added_element, parent_e)
        if index == -1:
            _error("ERROR:未找到增加条款所在位置条款的索引: %s" % str(target_attri))
            return False
        e = ET.fromstring(content, parser=None)
        e.attrib.update(new_attri)
        parent_e.insert(index+1, e)

        return True

    #替换target节点下的所有子条款
    def replace_elements(self, target_attri, new_attri, contents):


        #print "INFO:####正在替换所有子条款 %s" % str(target_attri)
        replaced_element = self.find_element(target_attri)
        if replaced_element is None:
            _error("ERROR:未找到被替换的条款: %s" % str(target_attri))
            return False

        replaced_element.attrib.update(new_attri)
        self.remove_all_child(replaced_element)

        for index, content in enumerate(contents):
            e = ET.fromstring(content, parser=None)
            replaced_element.insert(index, e)

        return True

    #替换target条款
    def replace_element(self, target_attri , new_attri, content):

        #print "INFO:####正在替换 %s" % str(target_attri)
        replaced_element = self.find_element(target_attri)
        if replaced_element is None:
            _error("ERROR:未找到被替换的条款: %s" % str(target_attri))
            return False
        parent_e = self.find_parent_element(self.root_e, replaced_element)
        if parent_e is None:
            _error("ERROR:未找到被替换条款的父条款: %s" % str(target_attri))
            return False

        replaced_index = self.get_element_index(replaced_element, parent_e)
        if replaced_index == -1:
            _error("ERROR:未找到被替换条款的索引: %s" % str(target_attri))
            return False

        e = ET.fromstring(content, parser=None)
        e.attrib.update(new_attri)
        parent_e.insert(replaced_index, e)
        parent_e.remove(replaced_element)
        return True


    def delete_element(self, target_attri):
        target_e = self.find_element(target_attri)
        parent_e = None

        #print "INFO:####正在删除 %s" % target_attri
        if target_e is not None:
            parent_e = self.find_parent_element(self.root_e, target_e)
        else:
            return False

        if parent_e is not None:
            parent_e.remove(target_e)
        else:
            return False

        return True

        # print target_e.attrib.get('title', "None")

    def save(self, file_path):
        self.et.write(file_path, encoding='utf-8', xml_declaration=None, default_namespace=None, method=None)

    def xml_md5(self):
        xml_string = ET.tostring(self.et.getroot(), encoding='utf-8', method=None)
        return md5(xml_string)
    def _print_element_info(self, e):
        if e is None:
            print "None"
            return
        info = ""
        for key, value in e.attrib.items():
            if key != 'note':
                info += "%s:%s " % (key, value)
            # print key, vlaue
        print info
